package com.jxlc.common.utils;

import com.jxlc.common.config.ConfigConst;
import com.jxlc.common.exception.GlobalException;
import com.jxlc.common.utils.file.FileUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipUtils {

    /**
     * @param zipFileName 压缩包名称 ，如 测试文件.zip
     * @param fileList    要压缩的文件列表（绝对路径），如 /home/person/test/测试.doc，/home/person/haha/测试.doc
     */
    public static void compressFiles(String zipFileName, Set<String> fileList) {
        compressFiles(ConfigConst.getZipPath() + "/", zipFileName, fileList);
    }

    /**
     * @param zipPathDir  压缩包路径 ，如 /home/data/zip-folder/
     * @param zipFileName 压缩包名称 ，如 测试文件.zip
     * @param fileList    要压缩的文件列表（绝对路径），如 /home/person/test/测试.doc，/home/person/haha/测试.doc
     */
    public static void compressFiles(String zipPathDir, String zipFileName, Set<String> fileList) {
        if (StringUtils.isEmpty(zipPathDir)) {
            throw new GlobalException("压缩文件路径不能为空");
        }
        if (StringUtils.isEmpty(zipFileName)) {
            throw new GlobalException("压缩文件名称不能为空");
        }
        ZipOutputStream zos;
        try {
            FileUtils.createFileDirIfNotExist(zipPathDir);
            zos = new ZipOutputStream(Files.newOutputStream(new File(zipPathDir + zipFileName + ".zip").toPath()));
            for (String filePath : fileList) {
                zipFile(new File(filePath), zipFileName, zos);
            }
            zos.flush();
            zos.close();
        } catch (Exception e) {
            System.out.println("压缩所有文件成zip包出错" + e.getMessage());
        }
    }

    private static void zipFile(File fileToZip, String fileName, ZipOutputStream zos) throws IOException {
        if (!fileToZip.exists() || fileToZip.isHidden()) {
            return;
        }
        if (fileToZip.isDirectory()) {
            if (fileName.endsWith("/")) {
                zos.putNextEntry(new ZipEntry(fileName));
            } else {
                zos.putNextEntry(new ZipEntry(fileName + "/"));
            }
            zos.closeEntry();
            File[] children = fileToZip.listFiles();
            if (children == null) {
                return;
            }
            for (File childFile : children) {
                zipFile(childFile, fileName + "/" + childFile.getName(), zos);
            }
            return;
        }
        FileInputStream fis = new FileInputStream(fileToZip);
        ZipEntry zipEntry = new ZipEntry(fileName);
        zos.putNextEntry(zipEntry);
        byte[] bytes = new byte[1024];
        int length;
        while ((length = fis.read(bytes)) >= 0) {
            zos.write(bytes, 0, length);
        }
        fis.close();
    }

    //测试方法
    public static void main(String[] args) {

        String zipPathDir = "D:/test/";
        String zipFileName = "测试文件.zip";
        Set<String> list = new HashSet<>();
        list.add("C:/Users/86157/Pictures/临时/11.png");

        compressFiles(zipPathDir, zipFileName, list);
    }
}

